package org.lalib.controller.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.lalib.entity.object.EHistoricalValue;
import org.lalib.entity.object.EItem;
import org.lalib.entity.object.variable.EVariable;
import org.lalib.mediator.MHistoricalValue;
import org.lalib.util.VariableTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Scope("prototype")
@Service("cHistoricalValueService")
public class CHistoricalValueService {

	@Autowired
	private MHistoricalValue mHistoricalValue;

	@Autowired
	private CVariableService cVariableService;

	@SuppressWarnings("rawtypes")
	public EItem getItemFromStringValue(String variableName, String value) {
		EHistoricalValue eHistoricalValue = mHistoricalValue.getItemFromStringValue(cVariableService.getVariableByName(variableName), value);
		if (eHistoricalValue == null)
			return null;
		return eHistoricalValue.getItem();
	}

	@SuppressWarnings("rawtypes")
	public void update(EHistoricalValue eHistoricalValue) {
		mHistoricalValue.update(eHistoricalValue);
	}

	public void setmHistoricalValue(MHistoricalValue mHistoricalValue) {
		this.mHistoricalValue = mHistoricalValue;
	}

	public void setcVariableService(CVariableService cVariableService) {
		this.cVariableService = cVariableService;
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getAllHistoricalValues(EItem item) {
		List<EHistoricalValue> eHistoricalValues = new ArrayList<>();
		List<EVariable> restVariables = new ArrayList<>();

		List<EVariable> variables = cVariableService.getAllVariablesForGivenCategoryList(item.getCategories());

		for (EVariable eVariable : variables) {
			EHistoricalValue eHistoricalValue = mHistoricalValue.getNewestValue(item, eVariable);
			if (eHistoricalValue == null)
				restVariables.add(eVariable);
			else
				eHistoricalValues.add(eHistoricalValue);
		}

		eHistoricalValues.addAll(getEmptyHistoricalValues(restVariables));
		return eHistoricalValues;
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getEmptyHistoricalValues(List<EVariable> variables) {
		List<EHistoricalValue> emptyHistorivalValues = new ArrayList<>();
		for (EVariable eVariable : variables) {
			EHistoricalValue eHistoricalValue = eVariable.initVariable();
			emptyHistorivalValues.add(eHistoricalValue);
		}
		return emptyHistorivalValues;
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getHistoricalValuesForTabName(EItem item, String tabname) {
		List<EHistoricalValue> values = new ArrayList<>();
		List<EVariable> variables = cVariableService.getVariables(tabname);
		List<EVariable> restVariables = new ArrayList<>();

		for (EVariable eVariable : variables) {
			EHistoricalValue eHistoricalValue = mHistoricalValue.getNewestValue(item, eVariable);
			if (eHistoricalValue == null)
				restVariables.add(eVariable);
			else
				values.add(eHistoricalValue);
		}

		values.addAll(getEmptyHistoricalValues(restVariables));
		return values;
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getStrippedValues(EItem item, List<EHistoricalValue> historicalValues) {
		List<EHistoricalValue> eHistoricalValues = new ArrayList<>();
		for (EHistoricalValue eHistoricalValue : historicalValues)
			if (!isCoreEmpty(eHistoricalValue)) {
				eHistoricalValue.setItem(item);
				eHistoricalValues.add(eHistoricalValue);
			}
		return eHistoricalValues;
	}

	@SuppressWarnings("rawtypes")
	private boolean isCoreEmpty(EHistoricalValue eHistoricalValue) {
		String variableType = eHistoricalValue.getVariable().getType();
		Object core = eHistoricalValue.getCore();
		if (variableType.equals(VariableTypes.STRINGVARIABLE))
			return core.toString().isEmpty();
		else if (variableType.equals(VariableTypes.BIGDECIMALVARIABLE))
			return new BigDecimal(core.toString()).equals(new BigDecimal("0.0"));
		else if (variableType.equals(VariableTypes.DATEVARIABLE))
			return core == null;
		else if (variableType.equals(VariableTypes.ENUMVARIABLE))
			return core.toString().isEmpty();
		return false;
	}

	@SuppressWarnings("rawtypes")
	public void save(List<EHistoricalValue> values) {
		for (EHistoricalValue eHistoricalValue : values)
			mHistoricalValue.update(eHistoricalValue);
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getHistoricalValues(EHistoricalValue value) {
		value = mHistoricalValue.getEntityById(value.getId());
		EItem item = value.getItem();
		EVariable variable = value.getVariable();
		List<EHistoricalValue> historicalValues = mHistoricalValue.getAllHistoricalValues(item, variable);
		if (historicalValues != null)
			return historicalValues;
		return new ArrayList<>();
	}

	@SuppressWarnings("rawtypes")
	public List<EHistoricalValue> getValues(EVariable variable, String value) {
		return mHistoricalValue.getValues(variable, value);
	}

	@SuppressWarnings("rawtypes")
	public EHistoricalValue getValue(EItem item, String variableName) {
		EVariable variable = cVariableService.getVariableByName(variableName);
		return mHistoricalValue.getNewestValue(item, variable);
	}
}